package org.xxpay.pay.channel.dwf.util;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.digest.DigestUtils;

import javax.crypto.*;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

import static java.nio.charset.StandardCharsets.UTF_8;

public class EncodeUtil {

    private static final String KEY_ALGORITHM = "AES";
    private static final String CIPHER_ALGORITHM = "AES/CBC/PKCS5Padding";

    /**
     * Decode from base64 , then decode by AES
     */
    public static String decode(String src, String key) {
        try {
            Cipher cipher = createCipher(key, Cipher.DECRYPT_MODE);
            byte[] decryptedBytes = cipher.doFinal(Base64.decodeBase64(src));
            return new String (decryptedBytes, UTF_8);
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(String.format("没有[%s]此类加密算法", CIPHER_ALGORITHM),e);
        } catch (NoSuchPaddingException e) {
            throw new RuntimeException(String.format("没有[%s]此类填充模式", CIPHER_ALGORITHM),e);
        } catch (InvalidKeyException e) {
            throw new RuntimeException("无效密钥",e);
        } catch (InvalidAlgorithmParameterException e) {
            throw new RuntimeException("无效密钥参数",e);
        } catch (BadPaddingException e) {
            throw new RuntimeException("错误填充模式",e);
        } catch (IllegalBlockSizeException e) {
            throw new RuntimeException("解密块大小不合法",e);
        }
    }

    public static String encode(String src, String key) {
        try {
            Cipher cipher = createCipher(key, Cipher.ENCRYPT_MODE);
            byte[] encryptedBytes = cipher.doFinal(src.getBytes(UTF_8));
            return Base64.encodeBase64String(encryptedBytes);
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(String.format("没有[%s]此类加密算法", CIPHER_ALGORITHM),e);
        } catch (NoSuchPaddingException e) {
            throw new RuntimeException(String.format("没有[%s]此类填充模式", CIPHER_ALGORITHM),e);
        } catch (InvalidKeyException e) {
            throw new RuntimeException("无效密钥",e);
        } catch (InvalidAlgorithmParameterException e) {
            throw new RuntimeException("无效密钥参数",e);
        } catch (BadPaddingException e) {
            throw new RuntimeException("错误填充模式",e);
        } catch (IllegalBlockSizeException e) {
            throw new RuntimeException("加密块大小不合法",e);
        }
    }

    private static Cipher createCipher(String key, int encryptMode) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException {
        byte[] keyBytes = key.getBytes();
        validateKey(keyBytes);
        Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
        SecretKey secretKey = new SecretKeySpec(keyBytes, KEY_ALGORITHM);
        cipher.init(encryptMode, secretKey, new IvParameterSpec(key.getBytes()));
        return cipher;
    }

    private static void validateKey(byte[] keyBytes) {
        // AES密钥长度为128bit、192bit、256bit，默认为128bit
        if (keyBytes.length % 8 != 0 || keyBytes.length < 16 || keyBytes.length > 32) {
            throw new RuntimeException("AES密钥长度不合法");
        }
    }

    public static String sign(String plain, String sha1Key) {
        return DigestUtils.sha1Hex(plain+sha1Key);
    }

    /**
     * 检查签名
     */
    public static boolean checkSign(String plain, String sign, String sha1Key) {
        return sign != null && sign.equalsIgnoreCase(sign(plain, sha1Key));
    }


    public static void main(String[] args) {
        String aesKey="14d63359e91590e5";
        String shaKey = "d644763961c2aad9";
        String encText = "Kw9jMzK4IXLrDokGS0gaqTVojvzMjcB+UYPilga3hyvrsgcD1HaNjpEC8GccnWcRl+6tb8VypXUuE6oHTO4g1yeZd9jGsGFemuQ9xQpSVIMtcGetkxNUIb7O1Xd7R2/94ehE8N1TV01N1capwZt22ZUh63ghMSQNnovnl0l1WFnspftIEWXFfSCDW0lbrAYM5gLUFI+PgD24LeVaTX6Y/xO5XhW1wwabIswG/bGNndsZQcmeTgck79/OTkrFGs7Dse/Phe+vodwSs+6nAiku8uO7Ih96CVtW5+jfWK2YqH9iG9BDAUH+hv9sBtbEIU1CHj7Bu7eQwuJFKth401W/ZblJeX1RkuKcznsF8SY6QVpU9BmXVHtmFYaQthv43FTFGtoxaXeXLgNnWasMKdKD4s2tqerDE+qP6iZQBty64+A=";
        String decode = decode(encText, aesKey);
        System.out.println(decode);
        String sign = "bb699b453412aaf402e56dc3beaedb37a49be883";
        System.out.println(DigestUtils.sha1Hex(decode + shaKey).equalsIgnoreCase(sign));
    }
}
